iT邦幫忙

2026 iThome 鐵人賽

DAY 16
0
Claude AI

從現場踩坑到 AI 工具 — IT Diagnostic Agent 開發實錄系列 第 16

Day 16 — 如果明天 Claude 漲價怎麼辦?

  • 分享至 

  • xImage
  •  

系列:從現場踩坑到 AI 工具 — IT Diagnostic Agent 開發實錄


一個沒發生的問題

先講清楚:Claude 沒有漲價,我也沒有遇到任何 API 政策問題。

這篇文章要講的,是一個還沒發生但我從第一版就在防的風險

而我認為這比事後補救的故事更值得寫——因為架構決策的價值,恰恰在於它讓某些故事永遠不會發生。


一個 IT 老兵的職業病

我做 IT 基礎建設二十年,這行有一條很基本的紀律:

不要讓任何單一供應商掐住你的咽喉。

  • 網路設備不會全押一家,至少核心和邊緣分開
  • 備份不會只有一份,異地一定要有
  • 對外線路不會只租一條,主備一定分不同 ISP

這不是不信任那些廠商。Cisco 沒有比較容易倒,中華電信不會突然斷線。

但**「他不會出問題」和「他出問題時我還活著」是兩件不同的事**。前者是預測,後者是設計。

當我開始接 LLM API 的時候,這個職業病自動就啟動了。


LLM API 的三個風險,沒有一個關於「品質」

我把風險列出來的時候發現一件事:我擔心的沒有一項是「Claude 不夠好」。

風險 1:定價變動

API 定價是廠商單方面決定的。今天的 token 價格不保證是明年的價格。

而我的工具沒有後端、不收費、使用者自己付 API 錢——這代表定價變動的痛感會直接打在使用者身上,我連幫他們吸收成本的機制都沒有。

風險 2:政策與可用性變動

這一項不是假設,而且時間點近得有點剛好。

2026 年 6 月 9 日,Anthropic 發布了 Claude Fable 5 和 Mythos 5。
6 月 12 日,這兩個模型的存取權限被暫停,以配合美國商務部的出口管制。
6 月 30 日管制解除,7 月 1 日恢復服務。

也就是說,那兩個模型有將近三週的時間是不能用的。

而我這個工具是 6 月 10 日上 GitHub 的。 剛好卡在 Fable 5 發布之後、暫停之前那兩天。

但我完全沒受影響。 因為我開發用的是 Sonnet 4.6,工具的預設模型也是 Sonnet 系列。整件事對我來說,就只是一則新聞。


那次事件真正的意義:我沒被影響是運氣,不是設計

我想特別把這件事寫清楚,因為它比「我遇到問題然後 Adapter Pattern 救了我」更有說服力。

如果我當初剛好選了 Fable 5 來開發、或是把它設成工具的預設模型——純粹是模型選擇上的一個隨手決定——那三週我的工具就是壞的。

我不會有任何預警。使用者也不會知道發生什麼事,他們只會看到 API 回錯誤。

這就是供應商依賴風險的真正形狀:它不是「某家廠商比較不可靠」,而是「你會不會被打到,取決於你在一個無關的決策點上剛好選了哪一邊」。

而任何依賴運氣的架構,都只是還沒被抽到而已。

Adapter Pattern 做的事情,就是把「有沒有被打到」從運氣的範疇,移到設計的範疇——不是保證不被打到,是保證被打到的時候,切換成本是一個下拉選單,而不是三週的停擺。

順帶一提,Anthropic 在暫停和恢復這兩件事上都發了公開說明。他們的處理在我看來是合規範圍內能做到最透明的了。

這正是我要強調的:風險不需要有人做錯事才會發生。 一個所有參與者都行為正確的世界裡,你的工具照樣可能壞掉三週。

風險 3:企業客戶的資料落地要求

這個是最現實的。

我後來實際接觸企業需求時發現,有些客戶的第一個問題不是「準不準」,是「資料會不會出公司」。

只要工具只能接雲端 API,這個問題就沒有答案。(Day 19 會專門講這件事。)


所以 Adapter Pattern 從第一版就在

Adapter Pattern(配接器模式)的概念很簡單:

定義一個統一的介面,讓不同的外部服務都被包裝成同一個形狀。

上層程式碼只認識那個介面,不認識任何一家供應商。

實際的程式碼是這樣:

async function callLLM(messages, systemPrompt){
  switch(currentProvider){
    case 'claude':  return await callClaude(messages, systemPrompt);
    case 'gemini':  return await callGemini(messages, systemPrompt);
    case 'openai':  return await callOpenAI(messages, systemPrompt);
    case 'ollama':  return await callOllama(messages, systemPrompt);
    default: throw new Error('Unknown provider: ' + currentProvider);
  }
}

這段程式碼十行,但它是整個 AI 功能的樞紐。


契約是什麼

Adapter Pattern 的核心不是那個 switch,是契約

在這個專案裡,契約是:

(messages, systemPrompt) => Promise<string>

輸入: 對話歷史陣列 + 系統提示字串
輸出: 一個字串

每一個 callXXX 函式都必須符合這個形狀。至於它內部怎麼把 messages 轉成該供應商要的格式、怎麼從一坨巢狀 JSON 裡挖出回覆文字——那是各自 adapter 的責任,上層完全不需要知道。

這代表整個工具裡只有四個函式知道供應商的存在。其他所有程式碼都只呼叫 callLLM


這個設計換到了什麼

新增一家供應商的成本,是寫一個函式,加一行 case。

不需要動決策樹、不需要動 UI、不需要動 systemPrompt、不需要動聊天記錄管理。

這件事的價值在後來得到驗證:當我要加 Ollama 支援的時候,實際的工作量遠比我預期的小。因為架構已經在那裡等著了。(Day 18 會講這個。)

反過來想,如果我第一版把 fetch('https://api.anthropic.com/...') 直接寫在送出按鈕的事件處理裡,後來要加三家供應商,我得回頭重構所有跟 AI 有關的程式碼。

那個重構不會很難,但它會很煩,而煩到一定程度的事情就不會被做。


結構化地看這個決定

可控 vs 不可控

不可控 可控
API 定價 換供應商的成本
廠商政策與法規 是否有替代路徑
服務可用性 切換所需的時間

我控制不了左邊任何一項。Adapter Pattern 做的事情是:把右邊那一欄從「幾天的重構」壓到「一個函式」。

風險沒有消失,但應對風險的成本被壓到接近零。

核心 vs 外部

核心是「工具要能用」。哪一家供應商提供智能,是外部條件。

一個把外部條件寫進核心邏輯的架構,會讓外部的每一次波動都變成核心的問題。

靜態 vs 動態

供應商生態是動態的。2026 年的最佳選擇不會是 2028 年的最佳選擇。

一個假設「供應商固定」的架構,是用靜態設計去對應動態現實。


一個需要說清楚的事

寫到這裡可能會有人覺得:這是不是在避險、在對 Claude 留一手?

不是。實際的情況是:

Claude 是這個工具的預設供應商,也是我自己開發時用的。

包括這個工具的多語言重構、深色模式、RWD 修正、Prompt 稽核,全部是 Claude 做的。這件事我在前面十五天已經寫得很清楚了。

Adapter Pattern 不是為了離開誰,是為了讓工具的壽命不綁在任何單一外部服務的壽命上

這兩件事完全不衝突。就像我信任中華電信,但我還是會租第二條線。

工程上的信任,是「我知道你會出問題時我有辦法」,不是「我相信你不會出問題」。


今天的反思

Adapter Pattern 是一個非常基礎的設計模式,任何一本 Design Patterns 的書都在講。

但我發現真正的難處不在「知道這個模式」,在判斷什麼東西該被抽象化

抽象化是有成本的——多一層間接、多一份心智負擔。抽象錯了地方,就是過度工程。

而判斷該抽象哪裡,靠的不是設計模式的知識,是你對哪些東西會變、哪些不會變的預測

我押了「供應商會變、契約不會變」。二十年的 IT 經驗告訴我這個押注很安全。


明天預告: 契約定好了,那實作起來呢?我原本以為接完 Claude 再接 Gemini 會很快——畢竟都是「送訊息、拿回覆」。實際上,兩家在八個維度上都不一樣。


作者:Rich Chang | IT 基礎建設工程師 | 越南・柬埔寨・台灣


上一篇
Day 15 — 我用 Claude 稽核自己的工具,結果找到一個 Prompt 漏洞
下一篇
Day 17 — Claude Adapter 實作,以及 Gemini 看起來很像其實完全不一樣
系列文
從現場踩坑到 AI 工具 — IT Diagnostic Agent 開發實錄22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言